/**
 * elancom Corporation copy right 2012 - 2015  
 *   
 * $Header$
 * $Id$
 * $Author$
 * $Date$
 * $Revision$
 */
package com.elancom.framework.web.context;

import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author elancom
 * @date 2012-7-13
 */
public class RequestContext {
	public static final ThreadLocal<RequestContext> THREAD_LOCAL = new ThreadLocal<RequestContext>();
	public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = RequestContext.class.getName() + ".CONTEXT";

	private ServletContext servletContext;

	private HttpServletRequest request;

	/**
	 * @param arg0
	 * @return
	 * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
	 */
	public Object getAttribute(String arg0) {
		return request.getAttribute(arg0);
	}

	/**
	 * @return
	 * @see javax.servlet.ServletRequest#getAttributeNames()
	 */
	@SuppressWarnings("unchecked")
	public Enumeration<String> getAttributeNames() {
		return request.getAttributeNames();
	}

	/**
	 * @return
	 * @see javax.servlet.http.HttpServletRequest#getMethod()
	 */
	public String getMethod() {
		return request.getMethod();
	}

	/**
	 * @param arg0
	 * @return
	 * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
	 */
	public String getParameter(String arg0) {
		return request.getParameter(arg0);
	}

	/**
	 * @return
	 * @see javax.servlet.ServletRequest#getParameterMap()
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> getParameterMap() {
		return request.getParameterMap();
	}

	/**
	 * @return
	 * @see javax.servlet.ServletRequest#getParameterNames()
	 */
	@SuppressWarnings("unchecked")
	public Enumeration<String> getParameterNames() {
		return request.getParameterNames();
	}

	/**
	 * @param arg0
	 * @return
	 * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
	 */
	public String[] getParameterValues(String arg0) {
		return request.getParameterValues(arg0);
	}

	/**
	 * @param arg0
	 * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
	 */
	public void removeAttribute(String arg0) {
		request.removeAttribute(arg0);
	}

	/**
	 * @param arg0
	 * @param arg1
	 * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object)
	 */
	public void setAttribute(String arg0, Object arg1) {
		request.setAttribute(arg0, arg1);
	}

	private HttpServletResponse response;

	private Map<String, Object> model;

	public static RequestContext getContext() {
		RequestContext context = THREAD_LOCAL.get();
		if (context == null) {
			throw new RuntimeException("当前不存在WEB请求上下文");
		}
		return context;
	}

	static RequestContext setContext(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
		RequestContext context = THREAD_LOCAL.get();
		if (context == null) {
			context = new RequestContext(request, response, servletContext, null);
			THREAD_LOCAL.set(context);
		}
		return context;
	}

	static void clear() {
		THREAD_LOCAL.remove();
		THREAD_LOCAL.set(null);
	}

	private RequestContext(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext, Map<String, Object> model) {
		initContext(request, response, servletContext, model);
	}

	protected void initContext(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext, Map<String, Object> model) {
		this.servletContext = servletContext;
		this.request = request;
		this.response = response;
		this.model = model;
	}

	protected final HttpServletRequest getRequest() {
		return this.request;
	}

	protected final ServletContext getServletContext() {
		return this.servletContext;
	}

	public final Map<String, Object> getModel() {
		return this.model;
	}

	public String getContextPath() {
		return request.getContextPath();
	}

	public String getContextUrl(String relativeUrl) {
		String url = getContextPath() + relativeUrl;
		if (this.response != null) {
			url = this.response.encodeURL(url);
		}
		return url;
	}

	public String getContextUrl(String relativeUrl, Map<String, ?> params) {
		String url = getContextPath() + relativeUrl;
		if (this.response != null) {
			url = this.response.encodeURL(url);
		}
		return url;
	}

	public HttpSession getSession() {
		return this.request.getSession();
	}
}
